<div data-title="Projects" style="height: 100%;">
  <div class="col-xs-3 main-left-column">

    <div class="list-group upcontrol" style="padding: 0; margin: 0; top: 5px;">
      <li class="list-group-item title" id="apps-header">
        <strong class="header">My Apps</strong>
        <div class="pull-right">
          <button style="margin-top: -5px;" class="btn btn-success btn-sm create-project-button"> <i class="fa fa-plus"></i> New</button>
          <button style="margin-top: -5px;" class="btn btn-success btn-sm" data-toggle="modal" data-type="app" data-target="#proj-manager-modal"> <i class="fa fa-download"></i> Import</button>
        </div>
      </li>
      <li class="list-group-item justify-content-between title" id="libs-header">
        <strong class="header">My Libs</strong>
        <div class="pull-right">
          <button style="margin-top: -5px;" class="btn btn-success btn-sm create-project-button"> <i class="fa fa-plus"></i> New</button>
          <button style="margin-top: -5px;" class="btn btn-success btn-sm" data-toggle="modal" data-type="lib" data-target="#proj-manager-modal"> <i class="fa fa-download"></i> Import</button>
        </div>
      </li>
    </div>

  </div>

  <div class="col-xs-9 main-right-column">
    <div class="editor-navbar">

      <span class="form-inline">
        <select class="form-control input-sm" id="file-dropdown"></select>
      </span>
      &nbsp;
      <button class="btn btn-sm btn-success" id="toolbar-save-button" data-toggle="tooltip" data-placement="top" title="Save&nbsp;currently&nbsp;opened&nbsp;file"><i class="fa fa-save"></i> </button>
      <button class="btn btn-sm btn-success" id="toolbar-delete-button" data-toggle="tooltip" data-placement="top" title="Delete&nbsp;currently&nbsp;opened&nbsp;file"><i class="fa fa-remove"></i> </button>
      <button class="btn btn-sm btn-success" id="toolbar-new-button" data-toggle="tooltip" data-placement="top" title="Create&nbsp;new&nbsp;file"><i class="fa fa-file-o"></i> </button>
      &nbsp;|&nbsp;&nbsp;
      <button class="btn btn-sm btn-success" id="toolbar-copy-button" data-toggle="tooltip" data-placement="top" title="Save&nbsp;file,&nbsp;copy&nbsp;to&nbsp;device,&nbsp;reboot&nbsp;device"><i class="fa fa-upload"></i> </button>
      &nbsp;|&nbsp;&nbsp;
      <span class="form-inline">
        <select class="form-control input-sm" id="arch-dropdown">
          <option>esp32</option>
          <option>esp8266</option>
          <option>cc3200</option>
        </select>
      </span>
      &nbsp;
      <button class="btn btn-sm btn-success" id="toolbar-build-button" data-toggle="tooltip" data-placement="top" title="Rebuild&nbsp;app&nbsp;firmware&nbsp;(slow)"><i class="fa fa-wrench"></i> </button>
      <button class="btn btn-sm btn-success" id="toolbar-flash-button" data-toggle="tooltip" data-placement="top" title="Flash&nbsp;app&nbsp;firmware&nbsp;to&nbsp;device&nbsp;(slow)"><i class="fa fa-flash"></i> </button>

      <!-- <button class="btn btn-sm btn-info pull-right" id="toolbar-share-button" disabled style="margin-right: 0;"><i class="fa fa-share-square-o"></i> Share this project</button> -->
    </div>
    <div class="form-group upcontrol">
      <div id="code_editor" class="editor"></div>
    </div>
  </div>
</div>


<li class="list-group-item local-project hidden row" id="local-entry-template" style="position: relative;">
  <span class="name col-xs-4 text-truncate"></span>
  <span class="title descr text-truncate col-xs-8"></span>
  <!-- <span class="tags descr hidden" style="margin-right: 10px;"></span> -->
</li>


<div class="btn-group project-control-toolbar hidden" id="ctl"
    style="position: absolute; top: 9px; right: 20px; ">
  <button class="btn btn-xs btn-default descr do-duplicate" data-toggle="tooltip" data-placement="top" title="Duplicate&nbsp;project"><i class="fa fa-copy"></i></button>
  <button class="btn btn-xs btn-default descr do-remove" data-toggle="tooltip" data-placement="top" title="Remove&nbsp;project"><i class="fa fa-remove"></i></button>
</div>


<div class="modal fade" id="proj-manager-modal" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h2 class="modal-title text-center"><span class="title">App Manager</span> &nbsp;&nbsp;&nbsp;<small class="hidden"><i class="fa fa-refresh fa-spin"></i> loading...</small> </h2>
      </div>
      <div class="modal-body">
        <div class="form form-inline" style="margin-bottom: 0px;">
          <div class="input-group xpull-right">
            <span class="input-group-addon"><i class="fa fa-search"></i></span>
            <input type="text" class="form-control" style="min-width: 17em;" id="proj-manager-filter-input" placeholder="type filter ...">
          </div>
        </div>
        <table class="table projects">
          <tr><th class="category-title header" colspan="5">Cloud integration</th></tr>
          <tr class="cloud"><th>Name</th><th>Title</th><th>Tags</th><th>Author</th><th>Import</th></tr>
          <tr><th class="category-title" colspan="5">Hardware</th></tr>
          <tr class="hardware"><th>Name</th><th>Title</th><th>Tags</th><th>Author</th><th>Import</th></tr>
          <tr><th class="category-title" colspan="5">Remote Management</th></tr>
          <tr class="remote-management"><th>Name</th><th>Title</th><th>Tags</th><th>Author</th><th>Import</th></tr>
          <tr><th class="category-title" colspan="5">Core</th></tr>
          <tr class="core"><th>Name</th><th>Title</th><th>Tags</th><th>Author</th><th>Import</th></tr>
        </table>
      </div>
    </div>
  </div>
</div>


<table role="table" class="table hidden">
  <tr id="remote-entry-template" class="remote-project">
    <td><a target="_blank" class="name" href></a></td>
    <td class="title"></td>
    <td class="tags"></td>
    <td class="author"></td>
    <td>
      <button class="btn btn-xs btn-success" style="padding: 0 15px;"><i class="fa fa-download"></i> Import</button>
      <div class="hidden imported descr"><i class="fa fa-check"></i> imported</div>
    </td>
  </tr>
</table>


<script>
  var code_editor = mkeditor('code_editor');

  var clone = function(sel) {
    return $(sel).clone().removeClass('hidden').removeAttr('id');
  };

  // Load file that user selects in a file dropdown
  $(document).off('change', '#file-dropdown');
  $(document).on('change', '#file-dropdown', function() {
    var el = $('.local-project.selected');
    var filename = $(this).val();
    var data = { type: el.attr('mos-type'), project: el.attr('mos-name'), filename: filename };
    $.ajax({url: '/p/get', global: true, data: data}).done(function(data){
      code_editor.lang = guesslang(filename);
      code_editor.setValue(atob(data.result || ''), -1);
      code_editor.session.setMode('ace/mode/' + code_editor.lang);
      code_editor.loadSnippets();
    }).always(function() {
    });
  });

  // User clicks on a project in a list. Switch project, load new set of files
  $(document).off('click', '.local-project');
  $(document).on('click', '.local-project', function() {
    var el = $(this);
    var d = { type: el.attr('mos-type'), project: el.attr('mos-name') };
    $.ajax({url: '/p/ls', global: true, data: d}).then(function(data) {
      $('.local-project').removeClass('selected');
      el.addClass('selected');  // Select project, to make file download work correctly
      $('#file-dropdown').empty();
      document.cookie = 'mos-type=' + d.type;
      document.cookie = 'mos-name=' + d.project;
      var ar = data.result || [];
      $.each(ar, function(i, v) {
        $('<option/>').text(v).appendTo('#file-dropdown');
      });
      var pname = 'src/' + el.attr('mos-name') + '.c';
      var s = $.inArray('fs/init.js', ar) >= 0 ? 'fs/init.js' :
              $.inArray('src/main.c', ar) >= 0 ? 'src/main.c' :
              $.inArray(pname, ar) >= 0 ? pname : 'README.md';
      $('#file-dropdown').val(s).change();
      $('#toolbar-build-button').prop('disabled', d.type == 'lib');
    }).always(function() {
      $('.local-project').removeClass('selected');
      el.addClass('selected');
    });
  });

  // Load local projects, populate project list and mark remote projects as downloaded
  var syncImportedProjects = function(type) {
    var dialogSelector = '#proj-manager-modal';
    var itemClass = 'local-' + type;
    var headerSelector = '#' + type + 's-header';

    return $.ajax({url: '/list-projects', data: {type: type}}).then(function(data) {
      $(dialogSelector + ' .btn').removeClass('hidden');
      $(dialogSelector + ' .imported').addClass('hidden');
      $('#ctl').addClass('hidden').appendTo('body');  // Save project toolbar before items removal
      $('.' + itemClass).remove();
      var keys = $.map(data.result || {}, function(v, k) { return k; });
      keys.sort(function (a, b) { return a < b ? 1 : -1; });
      $.each(keys, function(i, k) {
        var v = data.result[k];
        $(dialogSelector + ' [mos-name="' + k + '"] .btn').addClass('hidden');
        $(dialogSelector + ' [mos-name="' + k + '"] .imported').removeClass('hidden');
        var e = clone('#local-entry-template').addClass(itemClass);
        e.find('.name').text(k).attr({type: type, title: k});
        e.find('.title').text(v.description || '').attr({title: v.description || ''});
        e.attr({'mos-name': k, 'mos-type': type});
        $(headerSelector).after(e);
      });

      // Select last-used project
      var ptype = getCookie('mos-type');
      var pname = getCookie('mos-name');
      $('.local-project[mos-name="' + pname + '"][mos-type="' + ptype + '"]').click();
    });
  };

  $(document).off('click', '.remote-project .btn');
  $(document).on('click', '.remote-project .btn', function() {
    var btn = $(this);
    var type = btn.closest('[mos-type]').attr('mos-type');
    var url = $(this).closest('tr').find('a.name').attr('href');
    spin(btn);
    $.ajax({url: '/import-project', data: {url: url, type: type}}).always(function() {
      syncImportedProjects(type).always(function() {
        stopspin(btn);
      });
    }).fail(function() { stopspin(btn); });
  });

  var loadRemoteProjects = function(type) {
    var file = type + 's.json';
    var dialogSelector = '#proj-manager-modal';
    var org = 'mongoose-os-' + type + 's';
    return $.getJSON('https://mongoose-os.com/downloads/' + file).then(function(data) {
      $.each(data, function(k, v) {
        var tags = (v.tags || []).join(' ');

        // Figure out project category
        var category = 'core';
        if (tags.indexOf('cloud') > -1) category = 'cloud';
        if (tags.indexOf('rpc') > -1) category = 'remote-management';
        if (tags.indexOf('hw') > -1) category = 'hardware';

        var entry = clone('#remote-entry-template').insertAfter(dialogSelector + ' .' + category);
        entry.find('.name').text(k).attr({href: 'https://github.com/' + org + '/' + k});
        entry.find('.title').text(v.description || '');
        entry.find('.tags').text(tags);
        entry.find('.author').text((v.author || '').replace(/<.+>/, ''));
        entry.attr({'mos-name': k, 'mos-type': type});
      });
    });
  };

  $(document).off('mouseenter mouseleave', '.local-project');
  $(document).on('mouseenter', '.local-project', function(ev) {
    $('#ctl').removeClass('hidden').appendTo(this);
  }).on('mouseleave', '.local-project', function() {
    $('#ctl').addClass('hidden');
  });

  $(document).off('click', '.project-control-toolbar .do-remove');
  $(document).on('click', '.project-control-toolbar .do-remove', function() {
    if (!confirm('Click "OK" to delete this project.')) return;
    var el = $(this).closest('.local-project');
    var data = { type: el.attr('mos-type'), project: el.attr('mos-name'), filename: '.' };
    el.removeClass('selected');
    $.ajax({global:true, url: '/p/rm', data: data}).always(function() {
      syncImportedProjects(data.type);
    });
  });

  $(document).off('click', '.project-control-toolbar .do-duplicate');
  $(document).on('click', '.project-control-toolbar .do-duplicate', function() {
    var el = $(this).closest('.local-project');
    var data = { type: el.attr('mos-type'), project: el.attr('mos-name') };
    var fname = prompt('Enter project name, for example: ' + data.project + '-1');
    if (!fname || !fname.match(/^[\w_-]+$/)) {
      addLog('Bad project name. Use digits, letters, dashes, underscores');
      return;
    }
    data.target_name = fname;
    $.ajax({global:true, url: '/duplicate-project', data: data}).always(function() {
      syncImportedProjects(data.type);
    });
  });

  var saveFile = function() {
    var el = $('.local-project.selected');
    var data = {
      type: el.attr('mos-type'),
      project: el.attr('mos-name'),
      filename: $('#file-dropdown').val(),
      data: b64enc(code_editor.getValue()),
    };
    return $.ajax({global:true, url: '/p/set', data: data}).always(function() {
      $('#file-dropdown').change();
      addLog('File ' + data.filename + ' saved.\n');
    });
  };

  $(document).off('click', '#toolbar-save-button');
  $(document).on('click', '#toolbar-save-button', function() {
    var btn = $(this);
    spin(btn);
    saveFile().always(function() { stopspin(btn); });
  });

  $(document).off('click', '#toolbar-delete-button');
  $(document).on('click', '#toolbar-delete-button', function() {
    if (!confirm('Click "OK" to delete this file.')) return;
    var el = $('.local-project.selected');
    var d = { type: el.attr('mos-type'), project: el.attr('mos-name'), filename: $('#file-dropdown').val() };
    $.ajax({global:true, url: '/p/rm', data: d}).always(function() {
      $('.local-project.selected').click();
      addLog('File ' + d.filename + ' deleted.\n');
    });
  });

  $(document).off('click', '#toolbar-new-button');
  $(document).on('click', '#toolbar-new-button', function() {
    var fname = prompt('Enter file name, for example: fs/data.txt', '');
    if (!fname) return;
    var el = $('.local-project.selected');
    var d = { type: el.attr('mos-type'), project: el.attr('mos-name'), filename: fname, data: '' };
    $.ajax({global:true, url: '/p/set', data: d}).always(function() {
      $('.local-project.selected').click();
      addLog('File ' + d.filename + ' created.\n');
    });
  });

  $(document).off('click', '#toolbar-copy-button');
  $(document).on('click', '#toolbar-copy-button', function() {
    var btn = $(this);
    var fileName = $('#file-dropdown').val().replace(/^.*\//, '');
    var text = code_editor.getValue();
    if (!fileName) return;
    spin(btn);
    saveFile().then(function() {
      $.ajax({url: '/put', data: {data: text, path: fileName}}).then(function() {
        addLog('File ' + fileName + ' copied.\n');
        $.ajax({url: '/call', data: {method: 'Sys.Reboot'}}).always(function() {
          setTimeout(function() {
            $.ajax({url: '/call', data: {method: 'Sys.GetInfo'}}).always(function() {
              stopspin(btn);
            });
          }, 1000);
        });
      }).fail(function() { stopspin(btn); });
    });
  });

  $(document).off('click', '#toolbar-build-button');
  $(document).on('click', '#toolbar-build-button', function() {
    var btn = $(this);
    var el = $('.local-project.selected');
    var d = { app: el.attr('mos-name'), arch: $('#arch-dropdown').val() };
    if (!d.app || !d.arch) {
      new PNotify({ title: 'Need application and architecture selected', type: 'error' });
      return;
    }
    spin(btn);
    $.ajax({ global: false, url: '/app/build', data: d }).fail(function(xhr) {
      var errorText = xhr.responseJSON ? xhr.responseJSON.error : 'internal error';
      addLog('Build failed:' + errorText);
      new PNotify({ title: 'Build failed', text: errorText, type: 'error' });
    }).always(function(data) {
      stopspin(btn);
    });
  });

  $(document).off('click', '#toolbar-flash-button');
  $(document).on('click', '#toolbar-flash-button', function() {
    var btn = $(this);
    var el = $('.local-project.selected');
    var d = { project: el.attr('mos-name'), type: el.attr('mos-type') };
    spin(btn);
    $.ajax({ global: false, url: '/app/getfwpath', data: d }).then(function(data) {
      return $.ajax({global: false, url: '/flash', data: {firmware: data.result}});
    }).done(function() {
      stopspin(btn);
    });
  });

  $(document).off('click', '.create-project-button');
  $(document).on('click', '.create-project-button', function() {
    var type = $(this).closest('.title').attr('id') == 'libs-header' ? 'lib' : 'app';
    var fname = prompt('Enter project name, for example: my-' + type, '');
    if (!fname || !fname.match(/^[\w_-]+$/)) {
      addLog('Bad project name. Use digits, letters, dashes, underscores');
      return;
    }
    var d = {
      type: type,
      url: 'https://github.com/mongoose-os-' + type + 's/empty',
      target_name: fname,
    };
    var btn = spin(this);
    console.log(d);
    $.ajax({url: '/import-project', global: false, data: d}).always(function() {
      syncImportedProjects(type).always(function() {
        stopspin(btn);
      });
    }).always(function() { stopspin(btn); });
  });

  $(document).off('mos-devinfo');
  $(document).on('mos-devinfo', function() {
    var devAddr = $('.connect-input').val() || '';
    $('#toolbar-flash-button').prop('disabled', !!devAddr.match(/^(ws|mqtt|http)/));
    $('#arch-dropdown').val(ui.info ? ui.info.arch : 'esp32');
  });

  $(document).off('show.bs.modal', '#proj-manager-modal');
  $(document).on('show.bs.modal', '#proj-manager-modal', function(ev) {
    $('#proj-manager-filter-input').val('');
    var modal = $(this);
    var type = $(ev.relatedTarget).data('type');
    modal.find('h2 .title').text(type == 'lib' ? 'Library Manager' : 'App Manager');
    var loadingMessage = modal.find('h2 small').removeClass('hidden');
    modal.find('.remote-project').remove();
    loadRemoteProjects(type).always(function() {
      syncImportedProjects(type);
      loadingMessage.addClass('hidden');
    });
  });

  $(document).off('change', '#proj-manager-filter-input');
  $(document).on('change', '#proj-manager-filter-input', function(ev) {
    var text = $(this).val();
    $('#proj-manager-modal .remote-project').each(function(i, v) {
      var matchFound = function(sel) {
        var name = $(v).find(sel).text() || '';
        return name.indexOf(text) > -1;
      };
      var m = matchFound('.name') || matchFound('.title') ||
              matchFound('.tags') || matchFound('.author');
      $(v).toggle(m);
    });
  });

  syncImportedProjects('app');
  syncImportedProjects('lib');

  $(document).trigger('mos-devinfo');
  $('[data-toggle="tooltip"]').tooltip();
</script>
